package cn.com.surker.sale.service.impl;

import cn.com.surker.common.Code;
import cn.com.surker.enums.StateEnum;
import cn.com.surker.enums.sale.PaymentTypeEnum;
import cn.com.surker.enums.system.CheckEnum;
import cn.com.surker.sale.dao.SaleContractPaymentDao;
import cn.com.surker.sale.entity.SaleContractPayment;
import cn.com.surker.sale.service.SaleContractPaymentService;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 销售项目收款表 服务类
 * </p>
 *
 * @author admin
 * @since 2024-05-20
 */
public abstract class SaleContractPaymentBaseServiceImpl  extends ServiceImpl<SaleContractPaymentDao, SaleContractPayment> implements SaleContractPaymentService {

	@Resource
	protected SaleContractPaymentDao contractPaymentDao;

	/**
	 * 保存回款
	 * @param payment
	 * @return
	 */
	public SaleContractPayment savePayment(SaleContractPayment payment) {
		if (payment == null)
			return null;
		if (!StringUtils.isNull(payment.getPayTime()))
			payment.setSaleConfirmDate(payment.getPayTime());
		else
			payment.setSaleConfirmDate(new Date());
		Integer code = contractPaymentDao.insert(payment);
		if (code > 0) {

			return payment;
		}
		return null;
	}

	/**
	 * 修改回款信息
	 * @param payment
	 * @return
	 */
	public Integer updatePayment(SaleContractPayment payment) {
		if (payment == null)
			return Code.PARAM_EMPTY.getCode();

		SaleContractPayment contractPayment = contractPaymentDao.selectById(payment);
//		if (!StringUtils.isNull(payment.getMoney()))
//			contractPayment.setMoney(payment.getMoney());
//		if (!StringUtils.isNull(payment.getConId()))
//			contractPayment.setConId(payment.getConId());
		if (!StringUtils.isNull(payment.getPayOrigin()))
			contractPayment.setPayOrigin(payment.getPayOrigin());
		if (!StringUtils.isNull(payment.getConName()))
			contractPayment.setConName(payment.getConName());
		if (!StringUtils.isNull(payment.getSale()))
			contractPayment.setSale(payment.getSale());
		if (!StringUtils.isNull(payment.getCashier()))
			contractPayment.setCashier(payment.getCashier());
		if (!StringUtils.isNull(payment.getPayTime()))
			contractPayment.setPayTime(payment.getPayTime());
		if (!StringUtils.isNull(payment.getPayType()))
			contractPayment.setPayType(payment.getPayType());
		if (!StringUtils.isNull(payment.getType()))
			contractPayment.setType(payment.getType());
		if (!StringUtils.isNull(payment.getIsCheck()))
			contractPayment.setIsCheck(payment.getIsCheck());
		if (!StringUtils.isNull(payment.getIsPrint()))
			contractPayment.setIsPrint(payment.getIsPrint());
		if (!StringUtils.isNull(payment.getUpdater()))
			contractPayment.setUpdater(payment.getUpdater());
		if (!StringUtils.isNull(payment.getRemark()))
			contractPayment.setRemark(payment.getRemark());
		if (!StringUtils.isNull(payment.getSaleRemark()))
			contractPayment.setSaleRemark(payment.getSaleRemark());
		if (!StringUtils.isNull(payment.getIsReport()))
			contractPayment.setIsReport(payment.getIsReport());
		contractPayment.setUpdateTime(new Date());
		if (contractPayment.getIsCheck().intValue() == CheckEnum.HE.getCode().intValue())
			return Code.EXE_CONTRACT_EXAMINE.getCode();
		Integer code = contractPaymentDao.updateById(contractPayment);
		if (code > 0)
			return 0;
		return -1;
	}

	/**
	 * 修改回款状态
	 * @param id
	 * @param status
	 * @param updator
	 * @return
	 */
	public Integer updatePaymentStatus(Long id, Integer status, String updator) {
		if (StringUtils.isAllParamNull(id, status))
			return Code.PARAM_EMPTY.getCode();
		SaleContractPayment payment = contractPaymentDao.selectById(id);
		if (payment == null)
			return Code.ERROR_DATA.getCode();
		payment.setStatus(status);
		payment.setUpdater(updator);
		payment.setUpdateTime(new Date());
		Integer code = contractPaymentDao.updateById(payment);
		if (code > 0)
			return 0;
		return -1;
	}

	/**
	 * 分页查询合同列表
	 *
	 * @param orgId     站点列表
	 * @param conName   合同名称
	 * @param pageIndex 分页数据
	 * @param confirmType 1待认领 2已认领
	 * @param limit
	 * @return
	 */
	public IPage<SaleContractPayment> findPage(Long orgId, List<Long> orgIds, Long conId, String conName, String payOrigin,
											   Integer confirmType, String sale,Integer pageIndex, Integer limit) {
		QueryWrapper<SaleContractPayment> qw = new QueryWrapper<>();
		qw.eq("status", StateEnum.ENABLED.getCode());
		if (orgId != null) {
			qw.eq("org_id", orgId);
		}
		if (orgIds != null && orgIds.size() > 0) {
			qw.in("org_id", orgIds);
		}
		if (conId != null) {
			qw.eq("con_id", conId);
		}
		if (StringUtils.isNotBlank(conName)) {
			qw.like("con_name", conName);
		}
		if (StringUtils.isNotBlank(payOrigin)) {
			qw.like("pay_origin", payOrigin);
		}
		if (StringUtils.isNotBlank(sale)) {
			qw.eq("sale", sale);
		}
		if (confirmType != null) {
			if (confirmType.equals(1)) {
				//	待认领
				qw.isNull("sale");
			} else if (confirmType.equals(2)) {
				//	已认领
				qw.isNotNull("sale");
			}
		}
		//	qw.orderByDesc("pay_time");
		//	qw.last("ORDER BY CASE WHEN sale_add = 1 THEN 0 ELSE 1 END, pay_time DESC");
		qw.orderByAsc("CASE WHEN sale_add = 1 THEN 0 ELSE 1 END")
			.orderByDesc("pay_time");
		PageHelper.startPage(pageIndex, limit);
		IPage<SaleContractPayment> iPage = contractPaymentDao.selectPage(new Page<>((pageIndex + limit) / limit, limit), qw);
		/**分页插件**/
		if (!StringUtils.isNull(iPage.getRecords())) {
			PageInfo pageInfo = new PageInfo(iPage.getRecords());
			if (!StringUtils.isNull(pageInfo.getTotal()))
				iPage.setTotal(pageInfo.getTotal());
		}
		return iPage;
	}

	/**
	 * 查询销售的数据
	 *
	 * @param orgId       站点id
	 * @param orgIds      站点ids
	 * @param conId       合同id
	 * @param conName     合同名称
	 * @param payOrigin   付款单位
	 * @param confirmType 是否认领
	 * @param sale        销售人员
	 * @param pageIndex
	 * @param limit
	 * @return
	 */
	public IPage<SaleContractPayment> findSalePage(String searchVal, Long orgId, List<Long> orgIds, Long conId, String conName, String payOrigin,
									   Integer payType, Integer status,  Integer confirmType, String sale,String startTime,
									   String endTime, Integer isPrint,Integer isReport, Integer isCheck, Integer pageIndex, Integer limit) {
		QueryWrapper<SaleContractPayment> qw = new QueryWrapper<>();
		qw.eq("status", StateEnum.ENABLED.getCode());
		if (orgId != null) {
			qw.eq("org_id", orgId);
		}
		if (orgIds != null && orgIds.size() > 0) {
			qw.in("org_id", orgIds);
		}
		if (conId != null) {
			qw.eq("con_id", conId);
		}
		if (!StringUtils.isNull(isReport))
			qw.eq("is_report", isReport);
		if (!StringUtils.isNull(isPrint))
			qw.eq("is_print", isPrint);
		if (!StringUtils.isNull(startTime))
			qw.ge("pay_time", startTime);
		if (!StringUtils.isNull(endTime))
			qw.lt("pay_time", endTime);
		if (!StringUtils.isNull(searchVal))
			qw.and(orderWrapper -> orderWrapper.like("con_name", searchVal).or()
					.like("pay_origin", searchVal).or().like("remark", searchVal));
		if (StringUtils.isNotBlank(conName)) {
			qw.like("con_name", conName);
		}
		if (StringUtils.isNotBlank(payOrigin)) {
			qw.like("pay_origin", payOrigin);
		}
		/*if (StringUtils.isNotBlank(sale)) {
			qw.eq("sale", sale);
		}*/
		if (confirmType != null) {
			if (confirmType.equals(1)) {
				//	待认领
				qw.isNull("sale");
				qw.orderByAsc("con_id");
			} else if (confirmType.equals(2)) {
				//	已认领
				qw.isNotNull("sale");
			}
		}
		if (StringUtils.isNotBlank(sale)) {
			if (confirmType != null) {
				if (confirmType.equals(1)) {
					//	待认领
					qw.isNull("confirm_user");
				} else {
					//	已认领
					qw.and(e -> e.or().eq("sale", sale).or().eq("confirm_user", sale).or()
						.inSql("con_id", "select id from sale_contract where sale = '" + sale + "' or reckoner = '" + sale + "'"));
				}

			} else {
				//	没有认领状态,则表示查询所有未认领的数据和该销售认领的数据
				qw.and(e -> {
					e.or().eq("sale", sale).or().eq("confirm_user", sale).or().isNull("sale").
						or().inSql("con_id", "select id from sale_contract where sale = '" + sale + "' or reckoner = '" + sale + "'");
				});
			}
		}
		qw.orderByDesc("create_time");
//		PageHelper.startPage(pageIndex, limit);
		PageHelper.startPage(pageIndex, limit);
		IPage<SaleContractPayment> iPage = contractPaymentDao.selectPage(new Page<>((pageIndex + limit) / limit, limit), qw);
		/**分页插件**/
		if (!StringUtils.isNull(iPage.getRecords())) {
			PageInfo pageInfo = new PageInfo(iPage.getRecords());
			if (!StringUtils.isNull(pageInfo.getTotal()))
				iPage.setTotal(pageInfo.getTotal());
		}
		return iPage;
	}


	/**
	 * 查询回款记录中的销售人员
	 * @param orgId
	 * @return
	 */
	public List<Map<String, Object>> findSales(Long orgId) {
		if (StringUtils.isNull(orgId))
			return null;
		List<Map<String, Object>> saleList = contractPaymentDao.findSales(orgId);
		if (saleList == null || saleList.size() == 0)
			return null;
		return saleList;
	}

	public Map<String, Object> findSumMoney(String searchVal, Long orgId, Integer type, Integer isPrint, Integer isReport,
									 String sale, String startTime, String endTime) {
		List<SaleContractPayment> paymentList = contractPaymentDao.findSumMoney(searchVal, orgId, type, isPrint, isReport, sale, startTime, endTime);
		if (paymentList == null || paymentList.size() == 0)
			return null;
		Double sumMoney = 0.0;
		Map<Integer, String> typeMap = new HashMap<>();
		for (int i = 0; i < PaymentTypeEnum.values().length; i++) {
			typeMap.put(PaymentTypeEnum.values()[i].getCode(), PaymentTypeEnum.values()[i].getDescription());
		}
		Map<String, Object> map = new HashMap<>();
		for (int i = 0; i < paymentList.size(); i++) {
			SaleContractPayment payment = paymentList.get(i);
			if (typeMap.containsKey(payment.getType())) {
				map.put(typeMap.get(payment.getType()), StringUtils.formatDouble(payment.getMoney(), 2));
			}
			sumMoney += payment.getMoney();
		}
		map.put("合计", StringUtils.formatDouble(sumMoney, 2));
		return map;
	}

	/**
	 * 查询导出收款报表汇总
	 * @param orgId 公司ID
	 * @param sales 销售人员
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @return
	 */
	public Map<String, List<Map<String, Object>>> findExportData(Long orgId, String sales, String startTime, String endTime) {
		if (StringUtils.isAllParamNull(orgId, startTime, endTime))
			return null;
		QueryWrapper<SaleContractPayment> qw = new QueryWrapper<>();
		qw.eq("org_id", orgId);
		if (!StringUtils.isNull(sales)) {
			qw.and(e -> e.or().eq("sale", sales).or()
					.inSql("con_id", "select id from sale_contract where sale = '" + sales + "'"));
		}
		if (!StringUtils.isNull(startTime))
			qw.ge("pay_time", startTime);
		if (!StringUtils.isNull(endTime))
			qw.lt("pay_time", endTime);
		qw.eq("status", 0);
		qw.eq("is_report", 0);//导出已打印缴款单
		qw.isNotNull("sale");
		qw.isNotNull("con_id");
		qw.orderByAsc("sale", "pay_time");
		List<SaleContractPayment> paymentList = contractPaymentDao.selectList(qw);
		if (paymentList == null || paymentList.size() == 0)
			return null;

		Map<Integer, Object> payMap = new HashMap<>();
		for (int i = 0; i < PaymentTypeEnum.values().length; i++) {
			payMap.put(PaymentTypeEnum.values()[i].getCode(), PaymentTypeEnum.values()[i].getDescription());
		}
		Map<String, List<Map<String, Object>>> resultMap = new HashMap<>();
		for (int i = 0; i < paymentList.size(); i++) {
			Map<String, Object> temp = new HashMap<>();
			SaleContractPayment payment = paymentList.get(i);
			String today = "";
			if (!StringUtils.isNull(payment.getPayTime()))
				today = DateUtil.convertString(payment.getPayTime(), "yyyy-MM-dd");
			else
				today = DateUtil.convertString(payment.getSaleConfirmDate(), "yyyy-MM-dd");
			String sales_ = payment.getSale();
			temp.put("sales", sales_);
			temp.put("today", today);
			temp.put("payOrigin", payment.getPayOrigin());
			temp.put("conName", payment.getConName());
			temp.put("remark", payment.getRemark());
			temp.put("saleRemark", payment.getSaleRemark());
			for (int j = 0; j < PaymentTypeEnum.values().length; j++) {
				Double money = 0.0;
				if (PaymentTypeEnum.values()[j].getCode().intValue() == payment.getType().intValue())
					money = payment.getMoney();
				temp.put(PaymentTypeEnum.values()[j].getCode() + "", money);
			}
			if (resultMap.containsKey(sales_)) {
				List<Map<String, Object>> tempList = resultMap.get(sales_);
				tempList.add(temp);
				resultMap.put(sales_, tempList);
			} else {
				List<Map<String, Object>> tempList = new ArrayList<>();
				tempList.add(temp);
				resultMap.put(sales_, tempList);
			}
		}
		return resultMap;
	}
}
